﻿/********************************************************
 * Module/Class Name    : Envs (System Enviroment)
 * Purpose              : System Environment and static variables
 * Class Used           : EnvConstants
 * Chronological Development
 * Mukesh Arora    
 * Harwinder Singh 
 * Jagmohan Bhatt  
 ******************************************************/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Silverlight;
using System.Collections.Generic;
//using VAdvantage.DataService;
using System.Text;
using System.Windows.Resources;
using System.Windows.Media.Imaging;
using VAdvantage.Classes;
using System.Data;
using VAdvantage.Login;
using VAdvantage.Apps;
using VAdvantage.Logging;
using VAdvantage.Model;
using SilverlightDesktop.Controls;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.Automation;
using System.Xml.Linq;

namespace VAdvantage.Utility
{
    /// <summary>
    /// applicaton Environment Variable
    /// </summary>
    public class Envs : EnvConstants 
    {

        #region  "Declaration Variable"

        /** List of Unix browsers - sequence of test of existence */
        private static String[] UNIX_BROWSERS = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };

        public static String GOOGLE_MAPS_URL_PREFIX =
            "http://local.google.com/maps?q=";
        private static Context _sCtx = new Context();

        /**	Decimal 0	 */
        //public static Decimal ZERO = new Decimal(0.0);
        public const Decimal ZERO = Decimal.Zero;
        /**	Decimal 1	 */
        public const Decimal ONE = Decimal.One;
        /**	Decimal 100	 */
        public const Decimal ONEHUNDRED = 100.0M;

        /**	New Line 		 */
        public const String NL = "\r\n";

        /** list of hidden Windows				*/
        private static List<CFrame> s_hiddenWindows = new List<CFrame>();
        /** Closing Window Indicator			*/
        private static bool s_closingWindows = false;

        /**	Logging								*/
        private static VLogger _log = VLogger.GetVLogger(typeof(Envs).FullName);

        /*Default Window Page Size */
        public const int PAGE_SIZE = 50;

        /* Client + Org  Preference Level */
        public const int SHOW_CLIENT_ORG = 0;
        public const int SHOW_CLIENT_ONLY= 1;
        public const int SHOW_ORG_ONLY = 2;
        public const int HIDE_CLIENT_ORG = 3;
        //END

        /*Application Url [ ] */
        private static string applicationURL = null;

        //	Array of active Windows
        private static List<object> _sWindows = new List<object>(20);

        //All Modules Info
                           //  < id,< prefix,assemblyName,namespace,vesionno,vesionid,Name >>    
        private static Dictionary<int, Tuple<String,String, String, String, int,String>> _sModulesID = null;
                           //  < Prefix,< id,assemblyName,namespace,vesionno,vesionid,Name >>
        private static Dictionary<String, Tuple<int, String, String, String, int,String>> _sModulesPrefix = null;

        private static List<Tuple<int, String, String, String, int, String>> _sModuleVISPrefix = null;

        #endregion

        /// <summary>
        /// Get Client Context
        /// </summary>

        public static Ctx GetCtx()
        {
            return _sCtx;
        }   //  getCtx

        /// <summary>
        /// Get Context
        /// </summary>
        /// <returns></returns>
        public static Context GetContext()
        {
            return _sCtx;
        }

        /// <summary>
        /// Get Frame of Window
        /// </summary>
        /// <param name="container">Container</param>
        /// <returns>Form of container or null</returns>
        public static Form GetFrame(FrameworkElement container)
        {
            FrameworkElement element = container;
            while (element != null)
            {
                if (element is Form)
                {
                    return (Form)element;
                }
                //get parent
                element = element.Parent as FrameworkElement;
            }
            return null;
        }

        /// <summary>
        ///Parse Context replaces global or Window context @tag@ with actual value.
        /// </summary>
        /// <param name="ctx">ctx context</param>
        /// <param name="WindowNo">Number of Window</param>
        /// <param name="value">Message to be parsed</param>
        /// <param name="onlyWindow">onlyWindow  if true, no defaults are used</param>
        /// <returns>parsed String or "" if not successful</returns>
        public static string ParseContext(Ctx ctx, int WindowNo, string value,
         bool onlyWindow)
        {
            return ParseContext(ctx, WindowNo, value, onlyWindow, false);
        }

        /// <summary>
        ///	Parse Context replaces global or Window context @tag@ with actual value.
        ///  @tag@ are ignored otherwise "" is returned
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="WindowNo">Number of Window</param>
        /// <param name="value">value Message to be parsed</param>
        /// <param name="onlyWindow">if true, no defaults are used</param>
        /// <param name="ignoreUnparsable">if true, unsuccessful @return parsed String or "" if not successful and ignoreUnparsable</param>
        /// <returns>parsed context </returns>
        public static string ParseContext(Ctx ctx, int WindowNo, string value,
        bool onlyWindow, bool ignoreUnparsable)
        {
            if (value == null || value.Length == 0)
                return "";

            string token;

            StringBuilder outStr = new StringBuilder("");

            int i = value.IndexOf('@');
            // Check whether the @ is not the last in line (i.e. in EMailAdress or with wrong entries)
            while (i != -1 && i != value.LastIndexOf("@"))
            {
                outStr.Append(value.Substring(0, i));			// up to @
                value = value.Substring(i + 1, value.Length - i - 1);	// from first @

                int j = value.IndexOf('@');						// next @
                if (j < 0)
                {
                    //_log.log(Level.SEVERE, "No second tag: " + inStr);
                    return "";						//	no second tag
                }

                token = value.Substring(0, j);

                string ctxInfo = ctx.GetContext(WindowNo, token, onlyWindow);	// get context
                if (ctxInfo.Length == 0 && (token.StartsWith("#") || token.StartsWith("$")))
                    ctxInfo = ctx.GetContext(token);	// get global context
                if (ctxInfo.Length == 0)
                {
                    //_log.config("No Context Win=" + WindowNo + " for: " + token);
                    if (!ignoreUnparsable)
                        return "";						//	token not found
                }
                else
                    outStr.Append(ctxInfo);				// replace context with Context

                value = value.Substring(j + 1, value.Length - j - 1);	// from second @
                i = value.IndexOf('@');
            }
            outStr.Append(value);						// add the rest of the string

            return outStr.ToString();
        }	//	parseContext

        /// <summary>
        /// Get Preference.
        ///  <pre>
        ///		0)	Current Setting
        /// 		1) 	Window Preference
        ///		2) 	Global Preference
        ///		3)	Login settings
        ///		4)	Accounting settings
        ///  </pre>
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Window_ID">window no</param>
        /// <param name="context">Entity to search</param>
        /// <param name="system">System level preferences (vs. user defined)</param>
        /// <returns>preference value</returns>
        public static String GetPreference(Ctx ctx, int AD_Window_ID, String context, bool system)
        {
            if (ctx == null || context == null)
                throw new ArgumentException("Require Context");
            String retValue = null;
            //
            if (!system)	//	User Preferences
            {
                retValue = ctx.GetContext("P" + AD_Window_ID + "|" + context);//	Window Pref
                if (retValue.Length == 0)
                    retValue = ctx.GetContext("P|" + context);  			//	Global Pref
            }
            else			//	System Preferences
            {
                retValue = ctx.GetContext("#" + context);   				//	Login setting
                if (retValue.Length == 0)
                    retValue = ctx.GetContext("$" + context);   			//	Accounting setting
            }
            return (retValue == null ? "" : retValue);
        }	//	getPreference

        /// <summary>
        ///Clean up context for Window (i.e. delete it)
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="WindowNo"></param>
        public static void ClearWinContext(Context ctx, int windowNo)
        {
            if (ctx == null)
            {
                throw new ArgumentException("Require Context");
            }
            
            Object[] keys = ctx.KeySet().ToArray();
            for (int i = 0; i < keys.Length; i++)
            {
                String tag = keys[i].ToString();
                if (tag.StartsWith(windowNo + "|"))
                {
                    ctx.Remove(keys[i].ToString());
                }
            }

            //  Clear Lookup Cache
            MLookupCache.CacheReset(windowNo);
            RemoveWindow(windowNo);
        }

        /// <summary>
        /// Clear Context
        /// </summary>
        /// <param name="windowNo">windowno</param>
        public static void ClearWinContext(int windowNo)
        {
            ClearWinContext(_sCtx, windowNo);
        }

        /// <summary>
        ///Remove window from active list
        /// </summary>
        /// <param name="WindowNo"></param>
        private static void RemoveWindow(int windowNo)
        {
            if (windowNo > -1 && windowNo < _sWindows.Count)
                _sWindows[windowNo] = null;
        }	//	removeWindow

        /// <summary>
        /// 	Add Container and return WindowNo.
        /// </summary>
        /// <param name="win"></param>
        /// <returns>WindowNo used for context</returns>
        public static int CreateWindowNo(object win)
        {
            int retValue = _sWindows.Count;
            _sWindows.Insert(_sWindows.Count, win);
            return retValue;

        }	//

        /// <summary>
        //Get Frame of Window
        // </summary>
        // <param name="container"></param>
        /// <summary>
        public static SilverlightDesktop.Controls.Form GetForm(FrameworkElement container)
        {
            FrameworkElement element = container;
            while (element != null)
            {
                if (element is SilverlightDesktop.Controls.Form)
                    return (SilverlightDesktop.Controls.Form)element;
                element = (FrameworkElement)element.Parent;

            }
            return null;
        }	//	getFrame

        /**
	    *  Get Base Language code. (e.g. en-US)
	    *  @return Base Language
	    */
        public static String GetBaseAD_Language()
        {
            return "en_US";// s_languages[0].getAD_Language();
        }   //  getBase

        public static int Scale(Decimal d)
        {
            long l = Decimal.ToInt64(d);
            Decimal d1 = d - l;
            int[] intbits = Decimal.GetBits(d1);
            long l2 = Convert.ToInt64(intbits[0]);

            int scaleDigit = d1.ToString().Length - 2;
            if (l2 == 0)
                return 0;


            if (scaleDigit == -1)
            {
                return 0;
            }
            return scaleDigit;

        }

        public static int Signum(Decimal d)
        {
            return Math.Sign(d);
            //if (d > 0)
            //    return 1;
            //else if (d < 0)
            //    return -1;
            //else
            //    return 0;
        }

        //*******************Language Issues***********************************************************************

        /** Context Language identifier */
        public const String LANGUAGE = "#AD_Language";

        public static String GetAD_Language(Context ctx)
        {
            if (ctx != null)
            {
                String lang = ctx.GetContext(LANGUAGE);
                if (lang != null && lang.Length > 0)
                    return lang;
            }
            return Language.GetBaseAD_Language();
        }	//	getAD_Language

        public static String GetAD_Language(Ctx ctx)
        {
            if (ctx != null)
            {
                String lang = ctx.GetContext(LANGUAGE);
                if (lang != null && lang.Length > 0)
                    return lang;
            }
            return Language.GetBaseAD_Language();
        }	//

        /// <summary>
        /// Get System Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <returns>Language</returns>
        public static Language GetLanguage(Context ctx)
        {
            if (ctx != null)
            {
                String lang = ctx.GetContext(LANGUAGE);
                if (lang != null || lang.Length > 0)
                    return Language.GetLanguage(lang);
            }
            return Language.GetBaseLanguage();
        }	//	getLanguage

        /// <summary>
        /// Get System Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <returns>Language</returns>
        public static Language GetLanguage(Ctx ctx)
        {
            if (ctx != null)
            {
                String lang = ctx.GetContext(LANGUAGE);
                if (lang != null || lang.Length > 0)
                    return Language.GetLanguage(lang);
            }
            return Language.GetBaseLanguage();
        }	//

        /// <summary>
        ///  Get Login Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <returns>Language</returns>
        public static Language GetLoginLanguage(Context ctx)
        {
            return Language.GetLoginLanguage();
        }	//	getLanguage

        /// <summary>
        ///  Get Login Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <returns>Language</returns>
        public static Language GetLoginLanguage(Ctx ctx)
        {
            return Language.GetLoginLanguage();
        }

        public static int GetAD_Language_ID()
        {
            string sLang = GetLoginLanguage(Envs.GetCtx()).GetAD_Language();
            MLanguage language = MLanguage.Get(Envs.GetCtx(), sLang, null);
            return language.GetAD_Language_ID();
        }

        /// <summary>
        /// Verify Language.
        /// Check that language is supported by the system
        /// </summary>
        /// <param name="ctx">might be updated with new AD_Language</param>
        /// <param name="language">language</param>
        /// <returns>Language</returns>
        public static Language VerifyLanguage(Context ctx, Language language)
        {
            SetModuleInfo();


            if (language.IsBaseLanguage())
                return language;

            bool isSystemLanguage = false;
            List<String> AD_Languages = new List<String>();
            String sql = "SELECT DISTINCT AD_Language FROM AD_Message_Trl";
            System.Data.IDataReader dr = null;
            try
            {
                dr = VAdvantage.DataBase.DB.ExecuteReader(sql);
                while (dr.Read())
                {
                    String AD_Language = dr[0].ToString();
                    if (AD_Language.Equals(language.GetAD_Language()))
                    {
                        isSystemLanguage = true;
                        break;
                    }
                    AD_Languages.Add(AD_Language);
                }
                dr.Close();
            }
            catch
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            //	Found it
            if (isSystemLanguage)
                return language;
            //	No Language - set to System
            if (AD_Languages.Count <= 0)
            {
                return Language.GetBaseLanguage();
            }

            for (int i = 0; i < AD_Languages.Count; i++)
            {
                String AD_Language = (String)AD_Languages[i];	//	en_US
                String lang = AD_Language.Substring(0, 2);			//	en
                //
                String langCompare = language.GetAD_Language().Substring(0, 2);
                if (lang.Equals(langCompare))
                {
                    return Language.GetLanguage(AD_Language);
                }
            }

            //	We found same language
            //	if (!"0".equals(Msg.getMsg(AD_Language, "0")))

            return Language.GetBaseLanguage();
        }

        /// <summary>
        /// Get Module Data And set into static list
        /// </summary>
        private static void SetModuleInfo()
        {
            if (_sModulesID == null || _sModulesPrefix == null)
            {
                _sModulesID = new Dictionary<int, Tuple<string,string, string, string, Int32,String>>(5);
                _sModulesPrefix = new Dictionary<String, Tuple<int, string, string, string, Int32,String>>(5);
                _sModuleVISPrefix = new List <Tuple<int, string, string, string, Int32, String>>(2);
                try
                {

                    var client = AEnv.GetDataServiceDBClient();
                    bool waiting = false;
                    client.GetDataXMLCompleted +=(s,e)=>
                        {
                            waiting = false;
                            if(e.Error !=null || e.ServiceError != null)
                            {
                                return;
                            }
                            XElement ele = XElement.Parse(e.Result);
                            var ele2 = ele.Descendants("Table");

                            var listModule =
                                               (from t1 in ele.Descendants("Table")
                                                join temp in
                                                    (
                                                         from t2 in ele2
                                                         where Util.GetValueofString(t2, "Prefix") != "VIS_"
                                                         group t2 by Util.GetValueofString(t2, "Prefix") into grp
                                                         select new
                                                         {
                                                             id = grp.Key,
                                                             MaxVersion = grp.Max(t => new Version(Util.GetValueofString(t, "VersionNo")))
                                                         }
                                                    )
                                                on Util.GetValueofString(t1, "Prefix") equals temp.id
                                                where temp.MaxVersion == new Version(Util.GetValueofString(t1, "VersionNo"))
                                                select t1).Union
                                               (from u in ele2 where Util.GetValueofString(u, "Prefix") == "VIS_" select u);
                                              

                            //var lstModules =  from t in ele.Descendants("Table")
                            //                  join listMaxVersion


                            foreach (XElement dr in listModule)
                            {
                                if (Util.GetValueofString(dr,"Prefix") == "VIS_")
                                {
                                    _sModuleVISPrefix.Add(new Tuple<int, String, String, String, int, String>(Util.GetValueofInt(dr,"ID"),
                                                                     Util.GetValueofString(dr,"aName"), Util.GetValueofString(dr,"nSpace"),
                                                                     Util.GetValueofString(dr,"VersionNo"),
                                                                     Util.GetValueofInt(dr,"vID"), Util.GetValueofString(dr,"Name")));
                                }
                                else
                                {
                                    // < id, < prefix,namespace,versionno,versionid > >
                                    _sModulesID[Util.GetValueofInt(dr, "ID")] = new Tuple<String, String, String, String, int, String>
                                                                    (
                                                                     Util.GetValueofString(dr, "Prefix"),
                                                                     Util.GetValueofString(dr,"aName"), 
                                                                     Util.GetValueofString(dr,"nSpace"),
                                                                     Util.GetValueofString(dr, "VersionNo"),
                                                                     Util.GetValueofInt(dr, "vID"),
                                                                     Util.GetValueofString(dr, "Name")
                                                                    );
                                    // < prefix, < id,namespace,versionno,versionid > >
                                    _sModulesPrefix[Util.GetValueofString(dr, "Prefix")] = new Tuple<int, String, String, String, int, String>
                                                                    (
                                                                     Util.GetValueofInt(dr, "ID"),
                                                                     Util.GetValueofString(dr, "aName"), 
                                                                     Util.GetValueofString(dr, "nSpace"),
                                                                     Util.GetValueofString(dr, "VersionNo"),
                                                                     Util.GetValueofInt(dr, "vID"),
                                                                     Util.GetValueofString(dr, "Name")
                                                                    );
                                }
                            }
                        };

                    client.GetDataXMLAsync(@"SELECT m.AD_ModuleInfo_ID as ID,m.Prefix as Prefix,m.AssemblyName as aName,
                                                                                 m.NameSpace as nSpace,m.VersionNo as VersionNo, m.VersionID as vID,Name as Name 
                                                                          FROM AD_ModuleInfo m ", null, null);
                    client.CloseAsync();
                    waiting = true;
                    while (waiting)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                }
                catch( Exception e)
                {
                    _log.Warning("ML =>" + e.Message);
                }
            }
        }

        public static bool? IsModuleAlreadyInstalled(string prefix, string versionNo,string name)
        {
            bool? retValue = false;
            Version vInstalled = null, vImport = null;


            if (_sModulesPrefix.ContainsKey(prefix))
            {
                var values = _sModulesPrefix[prefix];

                vInstalled = new Version(values.Item4);
                vImport = new Version(versionNo);

                if (vInstalled >= vImport)
                {
                    retValue = true;
                }
                else
                {
                    retValue = null;
                }
            }
            else if (prefix == "VIS_")
            {
                for (int i = 0; i < _sModuleVISPrefix.Count; i++)
                {
                    if (name.Equals(_sModuleVISPrefix[i].Item6,StringComparison.OrdinalIgnoreCase))
                    {
                        vInstalled = new Version(_sModuleVISPrefix[i].Item4);
                        vImport = new Version(versionNo);

                        if (vInstalled >= vImport)
                        {
                            retValue =  true;
                        }
                        else
                        {
                            retValue = null;
                        }

                        break;
                    }
                }
            }

            vInstalled = null;
            vImport = null;
            return retValue;
       }

        

        /// <summary>
        /// Check passed name has module Prefix
        /// </summary>
        /// <param name="name">name to check</param>
        /// <param name="moduleInfo"> Tuple<assemblyName,Namespace> of module </param>
        /// <returns>true if has Module prefix</returns>
        public static bool HasModulePrefix(string name, out Tuple<String,String> moduleInfo )
        {
            moduleInfo = null;
            
            //Module prefix must has 
            if (name.Contains("_") && name.IndexOf("_") > 2)
            {
                string prefix = name.Substring(0, name.IndexOf("_") + 1);
                if(_sModulesPrefix.ContainsKey(prefix))
                {
                    var values = _sModulesPrefix[prefix];
                                                      //  'assembly name, Vession='version'
                    moduleInfo = new Tuple<string, string>(values.Item2 + ", Version=" + values.Item4, values.Item3);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Verify Language 
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="language">login language</param>
        /// <returns></returns>
        public static Language VerifyLanguage(Ctx ctx, Language language)
        {
            SetModuleInfo();

            if (language.IsBaseLanguage())
                return language;

            bool isSystemLanguage = false;
            List<String> AD_Languages = new List<String>();
            String sql = "SELECT DISTINCT AD_Language FROM AD_Message_Trl";
            System.Data.IDataReader dr = null;
            try
            {
                dr = VAdvantage.DataBase.DB.ExecuteReader(sql);
                while (dr.Read())
                {
                    String AD_Language = dr[0].ToString();
                    if (AD_Language.Equals(language.GetAD_Language()))
                    {
                        isSystemLanguage = true;
                        break;
                    }
                    AD_Languages.Add(AD_Language);
                }
                dr.Close();
            }
            catch
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            //	Found it
            if (isSystemLanguage)
                return language;
            //	No Language - set to System
            if (AD_Languages.Count <= 0)
            {
                return Language.GetBaseLanguage();
            }

            for (int i = 0; i < AD_Languages.Count; i++)
            {
                String AD_Language = (String)AD_Languages[i];	//	en_US
                String lang = AD_Language.Substring(0, 2);			//	en
                //
                String langCompare = language.GetAD_Language().Substring(0, 2);
                if (lang.Equals(langCompare))
                {
                    return Language.GetLanguage(AD_Language);
                }
            }

            //	We found same language
            //	if (!"0".equals(Msg.getMsg(AD_Language, "0")))

            return Language.GetBaseLanguage();
        }   //  verifyLanguage

        /// <summary>
        /// Check Base Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="tableName">table to be translated</param>
        /// <returns>true if base language and table not translated</returns>
        public static bool IsBaseLanguage(Context ctx, String tableName)
        {
            return Language.IsBaseLanguage(GetAD_Language(ctx));
        }	//	isBaseLanguage

        /// <summary>
        /// Check Base Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="tableName">table to be translated</param>
        /// <returns>true if base language and table not translated</returns>
        public static bool IsBaseLanguage(Ctx ctx, String tableName)
        {
            return Language.IsBaseLanguage(GetAD_Language(ctx));
        }	//	isBaseLanguage

        /// <summary>
        /// Check Base Language
        /// </summary>
        /// <param name="AD_Language">language</param>
        /// <param name="tableName">name of the table</param>
        /// <returns>true if base language</returns>
        public static bool IsBaseLanguage(String AD_Language, String tableName)
        {
            return Language.IsBaseLanguage(AD_Language);
        }	//	isBaseLanguage

        /// <summary>
        /// Check Base Language
        /// </summary>
        /// <param name="language">language</param>
        /// <param name="tableName">table name</param>
        /// <returns>true if base language</returns>
        public static bool IsBaseLanguage(Language language, String tableName)
        {
            return language.IsBaseLanguage();
        }	//	isBaseLanguage

        /// <summary>
        /// Table is in Base Translation (AD)
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public static bool IsBaseTranslation(string tableName)
        {
            if (tableName.StartsWith("AD")
                || tableName.Equals("C_Country_Trl"))
                return true;
            return false;
        }	//	

        /// <summary>
        ///Do we have Multi-Lingual Documents.
        // Set in DB.loadOrgs
        /// </summary>
        /// <param name="ctx"></param> 
        /// <returns>rue if multi lingual documents</returns>
        public static bool IsMultiLingualDocument(Ctx ctx)
        {
            return VAdvantage.Model.MClient.Get((Ctx)ctx).IsMultiLingualDocument();//
            //return false;
            //MClient.get(ctx).isMultiLingualDocument();
        }	//	isMultiLingualDocument

        /// <summary>
        ///Get Header info (connection, org, user)
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="WindowNo"></param>
        /// <returns></returns>
        public static String GetHeader(Ctx ctx, int windowNo)
        {
            StringBuilder sb = new StringBuilder();
            if (windowNo > 0)
                sb.Append(ctx.GetContext(windowNo, "WindowName", false)).Append("  ");
            sb.Append(ctx.GetContext("##AD_User_Name")).Append("@")
                .Append(ctx.GetContext("#AD_Org_Name")).Append(".")
                .Append(ctx.GetContext("#AD_Client_Name"));
            //.Append(" [").Append(VConnection.Get().ToString()).Append("]");//                   CConnection.get().toString()).append("]");
            return sb.ToString();
        }

        /// <summary>
        /// Show Window
        /// </summary>
        /// <param name="AD_Window_ID"></param>
        /// <returns></returns>
        public static bool ShowWindow(int AD_Window_ID)
        {
            for (int i = 0; i < s_hiddenWindows.Count; i++)
            {
                CFrame hidden = s_hiddenWindows[i];
                if (hidden.GetAD_Window_ID() == AD_Window_ID)
                {
                    s_hiddenWindows.RemoveAt(i);
                    // _log.Info(hidden.ToString());
                    hidden.Show();// .setVisible(true);
                    //hidden.BringToFront();
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        ///Hide Window
        /// </summary>
        /// <param name="window"></param>
        /// <returns></returns>
        public static bool HideWindow(CFrame window)
        {
            //  !DataBase.Ini.IsCacheWindow()
            if (!DataBase.Ini.IsCacheWindow() || s_closingWindows)
                return false;
            for (int i = 0; i < s_hiddenWindows.Count; i++)
            {
                CFrame hidden = s_hiddenWindows[i];
                //_log.Info(i + ": " + hidden);
                if (hidden.GetAD_Window_ID() == window.GetAD_Window_ID())
                    return false;	//	already there
            }
            if (window.GetAD_Window_ID() != 0)	//	workbench
            {
                try
                {
                    s_hiddenWindows.Add(window);
                    window.Hide();// .setVisible(false);
                    //_log.Info(window.ToString());
                    //	window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_ICONIFIED));
                    if (s_hiddenWindows.Count > 10)
                        s_hiddenWindows.RemoveAt(0);		//	sort of lru
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }

        /// <summary>
        /// Get ImageIcon.
        /// </summary>
        /// <param name="fileNameInImageDir"></param>
        /// <returns></returns>
        public static Image GetImageIcon(String fileNameInImageDir)
        {

            ImageSource src = LoadImageSource(fileNameInImageDir);

            if (src == null)
                return null;
            return new Image() { Source = src };

            //Image image = null;
            //ResourceManager rm = new ResourceManager("VAdvantage.Properties.Resources", typeof(VAdvantage.Properties.Resources).Assembly);
            //if (image == null && fileNameInImageDir.EndsWith("24.gif"))
            //{
            //    String png = fileNameInImageDir.Substring(0, fileNameInImageDir.Length - 6) + "32";// "32";//.png";
            //    object img = rm.GetObject(png);
            //    if (img != null)
            //        image = (Image)img;
            //}

            //if (image == null && fileNameInImageDir.EndsWith("10.gif"))
            //{
            //    String png = fileNameInImageDir.Substring(0, fileNameInImageDir.Length - 6) + "12";//;//; .png";
            

            //    object img = rm.GetObject(png);
            //    if (img != null)
            //        image = (Image)img;
            //}

            //if (image == null && fileNameInImageDir.EndsWith(".gif"))
            //{
            //    String png = fileNameInImageDir.Substring(0, fileNameInImageDir.Length - 4);//".png";
        
            //    object img = rm.GetObject(png);
            //    if (img != null)
            //        image = (Image)img;
            //}

            //if (image == null)
            //{
            //    
            //    string png = fileNameInImageDir.Substring(0, fileNameInImageDir.Length - 4);
            //    object img = rm.GetObject(png);
            //    if (img != null)
            //        image = (Image)img;
            //    else
            //    {
            //        _log.Log(Level.WARNING, "Not found: " + fileNameInImageDir);
            //    }
            //}
            //rm = null;
            //return image;

        }

        //<summary>
        //Return the Form pointer of WindowNo - or null
        //</summary>
        //<param name="WindowNo"></param>
        //<returns></returns>
        public static Control GetWindow(int windowNo)
        {
            Control retValue = null;
            try
            {
                retValue = GetForm((Control)_sWindows[windowNo]);
            }
            catch (Exception e)
            {
                _log.Log(Level.SEVERE, e.Message);
            }
            return retValue;
        }

        /// <summary>
        /// Clode Windows
        /// </summary>
        static void CloseWindows()
        {
            s_closingWindows = true;
            for (int i = 0; i < s_hiddenWindows.Count; i++)
            {
                CFrame hidden = s_hiddenWindows[i];
                hidden.Dispose();
            }
            s_hiddenWindows.Clear();
            s_closingWindows = false;
        }

        /// <summary>
        ///    Exit System
        /// </summary>
        /// <param name="status"></param>
        public static void ExitEnv(int status)
        {
            ////	End Session
            //MSession session = MSession.Get(Envs.GetContext(), false);	//	finish
            //if (session != null)
            //    session.Logout();
            //
            Reset(true);	// final cache reset
            _log.Info("");
            //
            VLogMgt.Shutdown();
            //
            bool OK = false;
            //if (VAdvantage.DataBase.Ini.IsClient())
            //    Environment.Exit(status);

        }	//	close

        /// <summary>
        /// Reset Cache
        /// </summary>
        /// <param name="finalCall">everything otherwise login data remains</param>
        public static void Reset(bool finalCall)
        {

            _log.Info("finalCall=" + finalCall);
            CloseWindows();
            _sWindows.Clear();

            if (_sModulesID != null)
            {
                _sModulesID.Clear();
                _sModulesID = null;
            }

            if (_sModulesPrefix != null)
            {
                _sModulesPrefix.Clear();
                _sModulesPrefix = null;
            }

            if (_sModulesID != null)
            {
                _sModulesID.Clear();
                _sModulesID = null;
            }

            if (_sModuleVISPrefix != null)
            {
                _sModuleVISPrefix.Clear();
                _sModuleVISPrefix = null;
            }

            //	Clear all Context
            if (finalCall)
            {
                _sCtx.Clear();
            }
            else	//	clear window context only
            {
                Object[] keys = _sCtx.KeySet().ToArray();
                for (int i = 0; i < keys.Length; i++)
                {
                    String tag = keys[i].ToString();
                    //if (Character.isDigit(tag.charAt(0)))
                    if (char.IsDigit(Convert.ToChar(tag.Substring(0, Convert.ToInt32(tag.Length - (tag.Length - 1))))))
                    {
                        _sCtx.Remove(keys[i].ToString());
                    }
                }
            }

            //	Cache
            CacheMgt.Get().Reset();
            // DB.CloseTarget();
            //	Reset Role Access
            if (!finalCall)
            {
                //DB.SetDBTarget(CConnection.get());
                // DB.SetDBTarget(DB.GetConnection());
                MRole defaultRole = MRole.GetDefault(_sCtx, false);
                if (defaultRole != null)
                {
                    defaultRole.LoadAccess(true);	//	Reload
                }
            }
            else
            {
                MRole.updateCache = false;
            }
        }

        /// <summary>
        /// Log Out [ Clean Up ]
        /// </summary>
        public static void LogOut()
        
        {
            for (int i = 2; i < _sWindows.Count; i++)
            {
                object o = _sWindows[i];
                if (o != null)
                {
                    if (o is Form)
                    {
                        ((SilverlightDesktop.Controls.Form)o).Close();
                    }
                    else if (o is Control)
                    {
                        Form frm = GetForm(o as FrameworkElement);
                        if (frm != null)
                        {
                            frm.Close();
                            frm = null;
                        }
                    }
                }
            }
            MSession session = MSession.Get(Envs.GetContext(), false);	//	finish
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    if (session != null)
                        session.Logout();
                });
            VLogErrorBuffer.Get(true).ResetBuffer(false);


            if (_desktop != null)
            {
                _desktop = null;
                
            }



            Reset(true);
        }

        /// <summary>
        /// Open default browser 
        /// </summary>
        /// <param name="url">Url to open </param>
        public static void StartBrowser(String url)
        {
            _log.Info(url);

            if (url.Contains("http://") || url.Contains("https://"))
            {
                ;
            }
            else
            {
                url = "http://" + url;
            }
            if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions )
            {
                try
                {
                    //MyHyperlinkButton button = new MyHyperlinkButton();
                    //button.NavigateUri = new Uri(url);
                    //button.TargetName = "_blank";
                    //button.ClickMe();
                    //return;

                    dynamic shell = AutomationFactory.CreateObject("Shell.Application");
                    shell.ShellExecute(url, "", "", "open", 1);
                }
                catch
                {
                }
                return;
            }


            try
            {
                //System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(url, UriKind.RelativeOrAbsolute), "_blank");
                System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(url, UriKind.Absolute), "_blank");
            }

            catch (Exception exc1)
            {

                // System.ComponentModel.Win32Exception is a known exception that occurs when Firefox is default browser.  

                // It actually opens the browser but STILL throws this exception so we can just ignore it.  If not this exception,

                // then attempt to open the URL in IE instead.

                //if (exc1.GetType().ToString() != "System.ComponentModel.Win32Exception")
                //

                // sometimes throws exception so we have to just ignore

                // this is a common .NET bug that no one online really has a great reason for so now we just need to try to open

                // the URL using IE if we can.

                try
                {
                    System.Windows.Browser.HtmlPage.Window.Navigate(new Uri("http://" + url, UriKind.Absolute), "_blank");
                    //System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("IExplore.exe", url);
                    //System.Diagnostics.Process.Start(startInfo);
                    //startInfo = null;
                }

                catch (Exception exc2)
                {
                    _log.Severe("Can't locate browser: " + exc2.Message);
                }
                //}
            }
        }

        /// <summary>
        /// Get Image Strem by image name from application resource
        /// </summary>
        /// <param name="imageName">image name</param>
        /// <returns>stream</returns>
        public static Stream GetImageStream(string imageName)
        {
            // Check From embedded  resource 
            Uri ur = new Uri(EnvConstants.ApplicationName + ";component/Images/" + imageName, UriKind.Relative);

            StreamResourceInfo sr = Application.GetResourceStream(ur);
            return sr.Stream;
        }

        /// <summary>
        /// Return BimapImage embedded as resource
        /// Only png Format Supported
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static BitmapImage LoadImageSource(string imageName)
        {
            // Check From embedded  resource 
            Uri ur = new Uri(EnvConstants.ApplicationName + ";component/Images/" + imageName, UriKind.Relative);

            StreamResourceInfo sr = Application.GetResourceStream(ur);

            BitmapImage bmp = new BitmapImage();
            try
            {
                bmp.SetSource(sr.Stream);
            }
            catch
            {
                bmp = null;
            }

            if (bmp == null)
            {
                // Get Image From Server Folder 
                //ur = new Uri("Images/" + imageName, UriKind.Relative);
                //bmp = new BitmapImage(ur);
            }

            return bmp;
        }

        /* Application Static Objects /

        /* parent appliaction desktop object */
        private static Explorer _desktop = null;
        /// <summary>
        /// Set Desktop entity [ base surface to open Window and forms ]
        /// </summary>
        /// <param name="desktop"></param>
        internal static void RegisterDesktop(SilverlightDesktop.Controls.Explorer desktop)
        {
            _desktop = desktop;
        }


        internal static Explorer Desktop
        {
            get
            {
                return _desktop;
            }
        }

        /// <summary>
        /// Register form with dektop [ must to open form ] 
        /// </summary>
        /// <param name="frm">from object </param>
        public static void RegisterWindowForm(Form frm)
        {
            frm.Explorer = _desktop;
        }
        private static BusyIndicator _indicator = null;
        /// <summary>
        /// Register busy indicator  [ common indicator to show while form or window is opening
        /// </summary>
        /// <param name="BusyWindow"></param>
        internal static void RegisterBusyIndicator(BusyIndicator BusyWindow)
        {
            _indicator = BusyWindow;
        }

        /// <summary>
        ///  Set State of busy indicator
        /// </summary>
        /// <param name="val"></param>
        public static void SetBusyIndicator(bool val)
        {
            _indicator.IsBusy = val;
        }

        /// <summary>
        /// show form s
        /// common function to register desktop, set size and show Form
        /// </summary>
        /// <param name="form"></param>
        public static void ShowForm(Form form)
        {
            if (form.Explorer == null)
            {    
                form.Explorer = _desktop;
            }

            if (form.Explorer.ActualWidth > 320)
            {
                form.Width = form.Explorer.ActualWidth - 320;
                form.Left = 160; 
            }
            else
            {
                form.Width = form.Explorer.ActualWidth;
            }

            if (form.Explorer.ActualHeight > 55)
            {
                form.Height = form.Explorer.ActualHeight - 20 - 35;
                form.Top = 10;
            }
            else
            {
                form.Height = form.Explorer.ActualHeight;
            }
            
            form.Show();
        }

        /// <summary>
        /// Get Application host Size
        /// </summary>
        /// <returns></returns>
        internal static Size GetHostSize()
        {
            Size s = new Size(_desktop.ActualWidth, _desktop.ActualHeight);
            return s;
        }

        /// <summary>
        /// Top expander pointer
        /// used to hide top expnader on menu click 
        /// </summary>
        public static Desktop.VExpender TopExpander
        {
            get;
            set;
        }

        /// <summary>
        /// Workspace Menu Item
        /// Used to enable and disable Workspace item while registration[key validated], or expired evaluation period
        /// </summary>
        //public static C1.Silverlight.C1MenuItem MenuWorkspace
        //{
        //    get;
        //    set;
        //}

        /// <summary>
        /// Is Workspace is enable and disable
        /// </summary>
        public static bool IsAllowWork
        {
            get;
            set;
        }

        /********************************* END *****************************/

        public class QueryParams
        {
            public String sql = "";
            public List<Object> parameters;

            /// <summary>
            /// 
            /// </summary>
            public QueryParams()
            {
                parameters = new List<Object>();
            }

            /// <summary>
            /// </summary>
            /// <param name="sql">Sql</param>
            /// <param name="parameters">Param</param>
            public QueryParams(String sql, Object[] localparam)
            {
                this.sql = sql;
                //this.params = Arrays.asList(params);
                this.parameters = localparam.ToList();
                //this.parameters.AddRange(localparam.ToList());
            }
        }

        public static bool IsStdColumn(string colName)

        {
            if (colName == "AD_USER_ID" || colName == "AD_ROLE_ID" || colName == "AD_CLIENT_ID" || colName == "AD_ORG_ID")
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Set thread culture according to login culture
        /// </summary>
        public static void SetThreadCulture()
        {
            System.Globalization.CultureInfo culture = Login.Language.GetLoginLanguage().GetCulture();//  language.GetCulture();
            System.Threading.Thread.CurrentThread.CurrentCulture = culture;
            //System.Threading.Thread.CurrentThread.CurrentUICulture = culture;    
        }

        public static Color GetColorFromHexString(string s)
        {

            byte a = System.Convert.ToByte("FF", 16);//Alpha should be 255
            byte r = System.Convert.ToByte(s.Substring(0, 2), 16);
            byte g = System.Convert.ToByte(s.Substring(2, 2), 16);
            byte b = System.Convert.ToByte(s.Substring(4, 2), 16);
            return Color.FromArgb(a, r, g, b);
        }

        public static Button GetZoomButton()
        {
            Button zoomButton = new Button() { Width = 20,Margin = new Thickness(1),Background = new SolidColorBrush(Colors.White) };
            zoomButton.Content = new Image() { Source = Envs.LoadImageSource("zoom.png")};

            ToolTipService.SetToolTip(zoomButton, Msg.GetMsg("Zoom"));
            return zoomButton  ;
        }

        /// <summary>
        /// Return culture based Client Org Show Level (User Preference Window) 
        /// order
        /// </summary>
        /// <returns></returns>

        public static string[] GetCOShowLevel()
        {
            return new string[4] { Msg.GetMsg("Client+Org"), Msg.GetMsg("Client"), Msg.GetMsg("Org"),Msg.GetMsg("None") };
        }

        public static int[] GetWorkSpacePageSize()
        {
            return new int[6] { 5,6,7,8,9,10 };
        }

        /// <summary>
        /// Get Application url
        /// *Must Call From UI[Main] Thread
        /// </summary>
        /// <returns>url string</returns>
        public static string GetApplicationURL()
        {
            if (applicationURL == null)
            {

                if (!System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.Contains("#ApplicationURL"))
                {
                    applicationURL = Application.Current.Host.Source.DnsSafeHost;
                    if (Application.Current.Host.Source.Port != 80)
                    {
                        applicationURL += ":" + Application.Current.Host.Source.Port;
                    }
                }
                else
                {
                    applicationURL = (String)System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings["#ApplicationURL"];
                }
                VLogger.Get().Info("URL => " + applicationURL);
            }
            return applicationURL;
        }

        internal static Type GetC1ModuleType(string clazz)
        {
            System.Reflection.Assembly asm = null;
            Type type = null;
            if (type == null)
            {
                try
                {
                    asm = System.Reflection.Assembly.Load("VC1Module, Version=1.0.0.0");
                    type = asm.GetType(clazz);
                }
                catch
                {
                    Logging.VLogger.Get().Severe("Could not load VC1Module Assembly or Type,missing Assemnly Reference");
                }
            }
            return type;

        }




    }
    
    public class MyHyperlinkButton : HyperlinkButton
    {
        public void ClickMe()
        {
            base.OnClick();
        }
    } 
}
